package com.heima.wemedia.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.common.utils.StringUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.api.feign.ApArticleFeignClient;
import com.heima.audit.baidu.BaiduImageScan;
import com.heima.audit.baidu.BaiduTextScan;
import com.heima.audit.tess4j.Tess4jClient;
import com.heima.file.service.FileStorageService;
import com.heima.model.article.dtos.ArticleDto;
import com.heima.model.common.constants.WmNewsConstants;
import com.heima.model.common.constants.WmNewsMessageConstants;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.wemedia.pojos.WmChannel;
import com.heima.model.wemedia.pojos.WmNews;
import com.heima.model.wemedia.pojos.WmSensitive;
import com.heima.model.wemedia.pojos.WmUser;
import com.heima.utils.common.SensitiveWordUtil;
import com.heima.wemedia.mapper.WmNewsMapper;
import com.heima.wemedia.service.ChannelService;
import com.heima.wemedia.service.WmNewsAuditService;
import com.heima.wemedia.service.WmSensitiveService;
import com.heima.wemedia.service.WmUserService;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageBuilder;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 自动审核
 *
 * @Author mr.chen
 * @Date 2025/6/25 16:06
 */
@Service
public class WmNewsAuditServiceImpl extends ServiceImpl<WmNewsMapper, WmNews> implements WmNewsAuditService {



    @Autowired
    private BaiduTextScan baiduTextScan;

    @Autowired
    private BaiduImageScan baiduImageScan;

    @Autowired
    private ApArticleFeignClient apArticleFeignClient;

    @Autowired
    private FileStorageService fileStorageService;

    @Autowired
    private ChannelService channelService;

    @Autowired
    private WmUserService wmUserService;

    @Autowired
    private WmSensitiveService wmSensitiveService;

    @Autowired
    private StringRedisTemplate redisTemplate;


    @Autowired
    private Tess4jClient tess4jClient;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    private final String SENSUTIVE = "Sensitive";

    /**
     * 自动审核
     *
     * @param wmNewsId
     */
    @Override
    @Transactional
    @Async("customThreadPool")
    public void WmNewsAudit(Long wmNewsId) {
        WmNews wmNewsone = this.getById(wmNewsId);
        List<String> images = new ArrayList<>();
        StringBuffer texts = new StringBuffer();

        //本地审核
        StringBuffer imageText = new StringBuffer();
        imageText.append(wmNewsone.getTitle()).append(wmNewsone.getLabels());

        List<Map> mapList = JSON.parseArray(wmNewsone.getContent(), Map.class);
        for (Map map : mapList) {
            if (map.get("type").equals("image")) {
                String image = map.get("value").toString();
                images.add(image);
            } else if (map.get("type").equals("text")) {
                texts.append(map.get("value").toString());
                imageText.append(map.get("value").toString());
            }
        }

        //组合图片
        if(StringUtils.isNotBlank(wmNewsone.getImages())) {
            List<String> list = Arrays.asList(wmNewsone.getImages().split(","));
            images.addAll(list);
            images = CollUtil.distinct(images);
        }

        //从redis获取敏感词
        List<String> range = redisTemplate.opsForList().range(SENSUTIVE, 0, -1);
        //存储敏感词集合
        List<String> stringList = new ArrayList<>();
        if (CollUtil.isNotEmpty(range)) {
            stringList.addAll(range);
        } else {
            List<WmSensitive> wmSensitiveList = wmSensitiveService.list();
            stringList = wmSensitiveList.stream().map(w -> {
                redisTemplate.opsForList().leftPush(SENSUTIVE, JSON.toJSONString(w.getSensitives()));
                return w.getSensitives();
            }).collect(Collectors.toList());
        }


        //提取图片文字
        if(CollUtil.isNotEmpty(images)){
            for (String image : images) {
                try {
                    byte[] bytes = fileStorageService.downLoadFile(image);
                    ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
                    BufferedImage bufferedImage = ImageIO.read(bis);
                    String text = tess4jClient.doOCR(bufferedImage);
                    imageText.append(text);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

        //本地审核
        SensitiveWordUtil.initMap(stringList);
        Map<String, Integer> stringIntegerMap = SensitiveWordUtil.matchWords(imageText.toString());
        if(stringIntegerMap.size()>0){
            //修改状态
            wmNewsone.setStatus((short) WmNewsConstants.BAIDU_FAIL);
            wmNewsone.setReason("文章审核失败");
            this.updateById(wmNewsone);
            return;
        }


        //添加标签和标题
        texts.append(wmNewsone.getTitle()).append(wmNewsone.getLabels());
        //转成string
        String stringText = texts.toString();
        //审核文章
        if (StrUtil.isNotBlank(stringText)) {
            //文本审核
            Integer contextType = baiduTextScan.textScan(stringText);
            if (contextType.equals(WmNewsConstants.BAIDU_FAIL) ) {
                wmNewsone.setStatus((short) WmNewsConstants.BAIDU_FAIL);
                wmNewsone.setReason("文章审核失败");
                this.updateById(wmNewsone);
                return;
            }else if(contextType.equals(WmNewsConstants.BAIDU_MAYBE)){
                wmNewsone.setStatus((short) WmNewsConstants.BAIDU_MAYBE);
                wmNewsone.setReason("文章审核疑似存在危险");
                this.updateById(wmNewsone);
                return;
            }
        }
        //审核图片
        if (CollUtil.isNotEmpty(images)) {
            for (String image : images) {
                byte[] bytes = fileStorageService.downLoadFile(image);
                Integer imageype = baiduImageScan.imageScan(bytes);
                if (imageype.equals(WmNewsConstants.BAIDU_FAIL)) {
                    wmNewsone.setStatus((short) WmNewsConstants.BAIDU_FAIL);
                    wmNewsone.setReason("图片审核失败");
                    this.updateById(wmNewsone);
                    return;
                }else if(imageype.equals(WmNewsConstants.BAIDU_MAYBE)){
                    wmNewsone.setStatus((short) WmNewsConstants.BAIDU_FAIL);
                    wmNewsone.setReason("图片审核疑似存在危险");
                    this.updateById(wmNewsone);
                    return;
                }
            }
        }

        //审核通过
        Date publishTime = wmNewsone.getPublishTime();
        Date date = new Date();

        ArticleDto dto = BeanUtil.toBean(wmNewsone, ArticleDto.class);
        dto.setLayout(wmNewsone.getType());//图片类型
        dto.setCreatedTime(wmNewsone.getCreatedTime());//创建时间
        //查询频道名称
        WmChannel wmChannel = channelService.getById(wmNewsone.getChannelId());
        dto.setId(wmNewsone.getArticleId());
        dto.setChannelName(wmChannel.getName());//频道名称
        long wmUserId = wmNewsone.getUserId();
        dto.setAuthorId(wmUserId);//作者id
        WmUser wmUser = wmUserService.getById(wmUserId);
        dto.setAuthorName(wmUser.getName());//作者姓名
        if (date.compareTo(publishTime) >= 0) {
            wmNewsone.setStatus((short) 9);
            wmNewsone.setReason("发布成功");
            ResponseResult<Long> saveResult = apArticleFeignClient.save(dto);
            Long articleId = saveResult.getData(); // 获取 articleId
            wmNewsone.setArticleId(articleId);
            this.updateById(wmNewsone);
        } else {
            wmNewsone.setStatus((short) 8);
            wmNewsone.setReason("待发布");
            this.updateById(wmNewsone);

            //求出延迟时间
            long publishTimeTime = publishTime.getTime();
            long time = new Date().getTime();
            Map<String, Object> hashMap = new HashMap<>();
            hashMap.put("wmNews",wmNewsone);
            hashMap.put("ArticleDto",dto);
            String jsonStr = JSONUtil.toJsonStr(hashMap);
            Message message = MessageBuilder.withBody(jsonStr.getBytes(StandardCharsets.UTF_8))
                    .setHeader("x-delay", publishTimeTime - time)
                    .setContentType(MessageProperties.CONTENT_TYPE_TEXT_PLAIN)
                    .build();
            rabbitTemplate.convertAndSend(WmNewsMessageConstants.WM_NEWS_DELAY_DIRECT,WmNewsMessageConstants.WM_NEWS_DELAY_DIRECT_ROUTINGKEY,message);
        }
    }
}